home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / pmpsrc11.zip / PMPTEST.C < prev    next >
Text File  |  1991-03-22  |  10KB  |  429 lines

  1. /*
  2.     pmptest.c
  3.  
  4.         A program to test the hardware (modem) setup for PMP
  5.  
  6.     August, 1989
  7.     Andrew C. Payne
  8. */
  9.  
  10. /* ----- Includes ----- */
  11. #include <stdio.h>
  12. #include <conio.h>
  13. #include <dos.h>
  14. #include <bios.h>
  15.  
  16. #define EXTERN
  17. #include "types.h"
  18. #include "ports.h"
  19. #include "keys.h"
  20.  
  21. int    monochrome;
  22. #define VIDEO    0x10
  23. #define TRUE    1
  24. #define FALSE    0
  25.  
  26. #define BITTIME 1988        /* 1200 baud bit time in ticks */
  27. #define CAPSIZE    2400        /* number of capture transitions */
  28.  
  29. int    TXState;        /* current transmit (PTT) state */
  30. int    TXLev;
  31.  
  32. int    prevRXCarrier;        /* prev values to minimize screen updates */
  33. int    prevRXLevel;
  34.  
  35. int    capbuf[CAPSIZE];
  36.  
  37. /* ----- Low Level Screen Control ----- */
  38.  
  39. /* v_setctype(start,end)
  40.     Set the cursor size:  start and end.
  41. */
  42. void cdecl v_setctype(int s,int e)
  43. {
  44.     _AH = 1;
  45.     _CH = s;
  46.     _CL = e;
  47.     geninterrupt(VIDEO);
  48. }
  49.  
  50. /* curoff()
  51.     Turns the cursor off.
  52. */
  53. void cdecl curoff(void)
  54. {
  55.     v_setctype(0x0f,0x0f);
  56. }
  57.  
  58. /* curon()
  59.     Turns the cursor on.
  60. */
  61. void cdecl curon(void)
  62. {
  63.     if(monochrome)
  64.         v_setctype(12,13);
  65.     else
  66.         v_setctype(6,7);
  67. }
  68.  
  69. /* putstring(x,y,len,attr,string)
  70.     Given an absolute screen position, a buffered length, and a string,
  71. write string to screen. (FAST!!)
  72. */
  73. void putstring(int x, int y, int len, char attr, char *s)
  74. {
  75.     char    buf[80*2];        /* buffer for string */
  76.     char    *p;
  77.     int    i;
  78.  
  79. /* fill buffer with screen data */
  80.     p = buf;
  81.     for(i=0; i<len; i++) {
  82.         if(*s)
  83.             *p++ = *s++;
  84.         else
  85.             *p++ = ' ';    /* buffer with spaces */
  86.  
  87.         *p++ = attr;        /* character attribute */
  88.     }
  89.  
  90. /* write string to screen */
  91.     puttext(x,y,x+len-1,y,buf);
  92. }
  93.  
  94. void TitleScreen()
  95. {
  96.     clrscr();
  97.     cprintf("┌─────────────────────────────────────────────────────────────────────────────┐\r\n");
  98.     cprintf("│  PMP Test  Version 0.7    Alignment and Test Program for Poor Man's Packet  │\r\n");
  99.     cprintf("│    Copyright (c) 1990 Andrew C. Payne     All rights reserved.              │\r\n");
  100.     cprintf("└─────────────────────────────────────────────────────────────────────────────┘\r\n");
  101.  
  102.     cprintf("  Commands:\r\n");
  103.     cprintf("    [ESC]     to exit\r\n");
  104.     cprintf("    [SPACE]   to toggle transmit on and off\r\n");
  105.     cprintf("    [F1]      for on-air modem alignment mode\r\n");
  106.     cprintf("    [F2]      to toggle transmit data level\r\n");
  107.     cprintf("    [F3]      to select 600hz transmit modulation\r\n");
  108.     cprintf("    [F4]      for loopback alignment (not implemented)\r\n");
  109.     gotoxy(1,22);
  110.     cprintf("     Carrier         Receive           Transmit         Push To\r\n");
  111.     cprintf("     Detect           Data               Data             Talk\r\n");
  112. }
  113.  
  114. void InitParameters()
  115. {
  116. /* default I/O ports */
  117.     PTTPort = TXPort = 0x378;
  118.     TXBit = 1;
  119.     PTTBit = 2;
  120.  
  121.     CDPort = RXPort = 0x379;
  122.     RXBit = 8;
  123.     CDBit = 0x80;
  124.     CDLevel = 0;
  125. }
  126.  
  127. /* ----- Low Level I/O ----- */
  128.  
  129. /* RXCarrier()
  130.     Returns TRUE if receive carrier detected.
  131. */
  132. int RXCarrier()
  133. {
  134.     register byte    x;
  135.  
  136.     x = inportb(CDPort) & CDBit;
  137.     return CDLevel ? x : !x;
  138. }
  139.  
  140. /* RXLevel()
  141.     Returns the current level of the RX data line.
  142. */
  143. int RXLevel()
  144. {
  145.     return (inportb(RXPort) & RXBit) == RXBit;
  146. }
  147.  
  148. /* TXKey(state)
  149.     Sets the transmitter state to the state given (TRUE = 1 = keyup).
  150.     Updates screen status.
  151. */
  152. void TXKey(int state)
  153. {
  154.     if(state) {
  155.         outportb(PTTPort,inportb(PTTPort) | PTTBit);
  156.         putstring(59,24,4,0x70," TX ");
  157.     } else {
  158.         outportb(PTTPort,inportb(PTTPort) & ~PTTBit);
  159.         putstring(59,24,4,0,"    ");
  160.     }
  161. }
  162.  
  163. /* TXLevel(x)
  164.     Sets the TX data level to the level specified.
  165.     Updates screen status.
  166. */
  167. void TXLevel(int x)
  168. {
  169.     if(x) {
  170.         putstring(42,24,4,0x70," TD ");
  171.         outportb(TXPort,inportb(TXPort) | TXBit);
  172.     } else {
  173.         outportb(TXPort,inportb(TXPort) & ~TXBit);
  174.         putstring(42,24,4,0,"    ");
  175.     }
  176.     TXLev = x;
  177. }
  178.  
  179. /* UpdateScreen()
  180.     Update the screen status to reflect the current Carrier Detect
  181.     level and the current receive level.
  182. */
  183. void UpdateScreen()
  184. {
  185.     int    t;
  186.  
  187. /* show status of CD */
  188.     if((t = RXCarrier()) != prevRXCarrier) {
  189.         prevRXCarrier = t;
  190.         if(prevRXCarrier)
  191.             putstring(7,24,4,0x70," CD ");
  192.         else
  193.             putstring(7,24,4,0,"    ");
  194.     }
  195.  
  196. /* show receive level */
  197.     if((t = RXLevel()) != prevRXLevel) {
  198.         prevRXLevel = t;
  199.         if(prevRXLevel)
  200.             putstring(23,24,4,0x70," RD ");
  201.         else
  202.             putstring(23,24,4,0,"    ");
  203.     }
  204. }
  205.  
  206. /* SquareWave()
  207.     Generate a 600hz square wave on the output until a key is pressed.
  208. */
  209. void SquareWave(void)
  210. {
  211.     word    from;
  212.  
  213. /* show what is going on on the screen */
  214.     gotoxy(1,13);
  215.     cprintf("┌────────────────────────────── 600hz Transmit ───────────────────────────────┐\r\n");
  216.     cprintf("│                                                                             │\r\n");
  217.     cprintf("│                      Transmitting 600hz square wave                         │\r\n");
  218.     cprintf("│                                                                             │\r\n");
  219.     cprintf("│                                                                             │\r\n");
  220.     cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
  221.  
  222.     from = timer();
  223.     while(!keypressed())        /* wait tell key interrupt */
  224.         transit(from -= BITTIME);
  225.  
  226.     putstring(1,13,79,0,"");        /* clear the lines */
  227.     putstring(1,14,79,0,"");
  228.     putstring(1,15,79,0,"");
  229.     putstring(1,16,79,0,"");
  230.     putstring(1,17,79,0,"");
  231.     putstring(1,18,79,0,"");
  232.     getkey();                /* gobble */
  233. }
  234.  
  235. /* Alignment()
  236.     Waits for carrier detect (or user keystroke), and captures a
  237.     few transitions of data.  Computes and displays alignment information
  238.     from transition timing.
  239. */
  240. void Alignment(void)
  241. {
  242.     int    i;
  243.     word    t,t1,t2;
  244.     int    actual,delta;
  245.     long    deltahi,deltalo;
  246.     int    deltahict, deltaloct;
  247.     char    s[100];
  248.  
  249. /* show what is going on on the screen */
  250.     gotoxy(1,13);
  251.     cprintf("┌────────────────────────────── Modem Alignment ──────────────────────────────┐\r\n");
  252.     cprintf("│   Adjust modem for lowest numbers possible  (see manual for more info)      │\r\n");
  253.     cprintf("│                                                                             │\r\n");
  254.     cprintf("│                                                                             │\r\n");
  255.     cprintf("│                                                                             │\r\n");
  256.     cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
  257.  
  258. loop:
  259.     while(!RXCarrier() && !keypressed())
  260.         ;
  261.  
  262.     if(keypressed()) {
  263.         putstring(1,13,79,0,"");        /* clear the lines */
  264.         putstring(1,14,79,0,"");
  265.         putstring(1,15,79,0,"");
  266.         putstring(1,16,79,0,"");
  267.         putstring(1,17,79,0,"");
  268.         putstring(1,18,79,0,"");
  269.         getkey();                /* gobble key */
  270.         return;
  271.     }
  272.     UpdateScreen();
  273.  
  274. /* start capture */
  275.     deltahi = deltalo = deltahict = deltaloct = 0;
  276.     disable();
  277.     for(i=0; i<CAPSIZE; i++) {
  278.         t2 = waittrans(t1-20000);
  279.         t = t1 - t2;
  280.         t1 = t2;
  281.         actual = ((t + 994) / BITTIME) * BITTIME;
  282.         delta = actual - t;
  283.         if(RXLevel()) {
  284.             deltahi += delta;
  285.             deltahict++;
  286.         } else {
  287.             deltalo += delta;
  288.             deltaloct++;
  289.         }
  290.         if(!RXCarrier())
  291.             break;
  292.     }
  293.     enable();
  294.     UpdateScreen();
  295.     sprintf(s,"Low -> High error:  %5ld%%    High -> Low error:  %5ld%%",
  296.         (deltahi / deltahict) * (long)100 / BITTIME,
  297.         (deltalo / deltaloct) * (long)100 / BITTIME);
  298.     putstring(15,16,60,7,s);
  299.     delay(1000);
  300.  
  301.     goto loop;
  302. }
  303.  
  304. /* Loopback()
  305.     Does a loopback alignemnt.  Assumes that the transmit audio is
  306.     looped back into the receive audio.
  307. */
  308. void Loopback()
  309. {
  310.     word    t,t1,d;
  311.     int    i,j,k;
  312.     long    deltalo, deltahi;
  313.     char    s[100];
  314.  
  315. /* show what's going on */
  316.     gotoxy(1,13);
  317.     cprintf("┌──────────────────────────── Loopback Alignment ─────────────────────────────┐\r\n");
  318.     cprintf("│   Adjust modem for lowest numbers possible  (see manual for more info)      │\r\n");
  319.     cprintf("│                                                                             │\r\n");
  320.     cprintf("│                                                                             │\r\n");
  321.     cprintf("│                                                                             │\r\n");
  322.     cprintf("└─────────────────────────── Press Any Key To Exit ───────────────────────────┘\r\n");
  323.  
  324. /* loop until keypressed */
  325.     while(!keypressed()) {
  326.         deltalo = deltahi = 0;
  327.         TXLevel(0);
  328.         delay(100);
  329.         disable();
  330.         deltahi = 0;
  331.         t = timer();
  332.         j = RXLevel();
  333.         transit(t -= BITTIME);
  334.         waituntil(t -= 50000);
  335.         waituntil(t -= 50000);
  336.         i = RXLevel();
  337.         enable();
  338.         delay(100);
  339.         cprintf("%d %d\r\n",j,i);
  340.     }
  341.     getkey();
  342.  
  343. #ifdef ANDY
  344. /* do a second-long sample */
  345.         for(i=0; i<600; i++) {
  346.  
  347. /* do a low->high transition */
  348.             transit(t -= BITTIME);        /* do a transition */
  349.             deltahi = t - waittrans(t - 50000);
  350.             break;
  351.             d = RXLevel();
  352.             if(d)
  353.                 deltahi++;
  354.  
  355. /* do a high-low transition */
  356.             transit(t -= BITTIME);        /* do a transition */
  357.             d = RXLevel();
  358.             if(!d)
  359.                 deltalo++;
  360.         }
  361.         enable();
  362.  
  363.         sprintf(s,"%5ld  %5ld",
  364.             deltahi, deltalo);
  365.         putstring(15,16,60,7,s);
  366.     }
  367.     getkey();                /* gobble the key */
  368. #endif
  369. }
  370.  
  371. /* HandleKey()
  372.     Handles user's keystrokes.
  373. */
  374. int HandleKey()
  375. {
  376.     KEY    k;
  377.  
  378.     switch(getkey()) {
  379.         case ESC:
  380.         case ALTX:
  381.             return TRUE;        /* done! */
  382.         case SPC:
  383.             TXState = !TXState;
  384.             TXKey(TXState);
  385.             break;
  386.         case F1:            /* on-air alignment */
  387.             Alignment();
  388.             break;
  389.         case F2:            /* toggle TX level */
  390.             TXLev = !TXLev;
  391.             TXLevel(TXLev);
  392.             break;
  393.         case F3:            /* 600hz square wave */
  394.             SquareWave();
  395.             break;
  396.         case F4:            /* loopback test */
  397. /*            Loopback();
  398. */
  399.             break;
  400.     }
  401.     return FALSE;
  402. }
  403.  
  404. /* ----- Main Program ----- */
  405.  
  406. main(int argc, char **argv)
  407. {
  408. /* Initialize */
  409.     monochrome = TRUE;
  410.     TXKey(TXState = FALSE);
  411.     TitleScreen();
  412.     curoff();
  413.     InitParameters();
  414.  
  415. /* loop, handling keystrokes and showing current status */
  416.     while(TRUE) {
  417.         if(keypressed()) {
  418.             if(HandleKey())
  419.                 break;
  420.         }
  421.         UpdateScreen();
  422.     }
  423.  
  424. /* clean up and exit */
  425.     clrscr();
  426.     curon();
  427.     TXKey(FALSE);        /* drop transmit */
  428.     _exit(0);
  429. }